Skip to content

Conversation

daveinglis
Copy link

@daveinglis daveinglis commented Sep 16, 2025

  • FileManager handles long file name prefixes on Windows correctly.
    This keeps any UNC long file prefix (\\?\) out of
    URL that were relative and then resolved to absolute urls.

@daveinglis
Copy link
Author

@swift-ci test

@jakepetroules
Copy link
Contributor

Could we add tests for this?

@daveinglis
Copy link
Author

test added

@daveinglis
Copy link
Author

@swift-ci test

@daveinglis daveinglis force-pushed the strip_unc_lf_preifx branch 3 times, most recently from 82bf6bf to 88dcf1b Compare September 18, 2025 15:42
@daveinglis
Copy link
Author

@swift-ci test

@daveinglis
Copy link
Author

@swift-ci test windows

@daveinglis
Copy link
Author

@swift-ci test linux

@daveinglis
Copy link
Author

@swift-ci test


// Get original directory for restoration
var originalBuffer = [CChar](repeating: 0, count: Int(MAX_PATH))
guard _NS_getcwd(&originalBuffer, originalBuffer.count) != nil else {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the user level API that this is supposed to affect? _NS_getcwd is clearly for internal use only.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it looks like NSURL::fileSystemRepresentation with a relative path would use it to make it absolute, could be other places too but it was that test that was failing due to the long path prefix

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of calling directly to _NS_getcwd from the test, it'd be great if this test could call the client-level API that this affects. So if changing _NS_getcwd is required here because it impacts the FSR of an NSURL, could we instead write a test that checks the output of NSURL's FSR to ensure it's the right value? To me that would be a more valuable unit test to make sure the client level behavior is correct regardless of the output of this function (since as we remove more and more C code this function may go away, but our Swift API won't)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So there is a test (test_fileURLWithPath) that was failing due this prefix, specifically;

        path = TestURL.gFileDoesNotExistName
        url = NSURL(fileURLWithPath: path)
        XCTAssertFalse(url.hasDirectoryPath, "did not expect URL with directory path: \(url)")
        let fileSystemRep = url.fileSystemRepresentation
        let actualLength = strlen(fileSystemRep)
        // 1 for path separator
        let expectedLength = UInt(strlen(TestURL.gFileDoesNotExistName)) + TestURL.gRelativeOffsetFromBaseCurrentWorkingDirectory
        XCTAssertEqual(UInt(actualLength), expectedLength, "fileSystemRepresentation was too short")

Would this be testing the client-level API around how this is being used?

Copy link
Contributor

@parkera parkera left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's identify the user level API this is supposed to change - this CF API should not be used directly, and in any case is all eventually being replaced by Swift code.

@daveinglis
Copy link
Author

So the swift API that would be affected was going to have this as well (FileManager.currentDirectoryPath - see swiftlang/swift-foundation#1479) but that PR also cause the NSURL test to fail so it was reverted (swiftlang/swift-foundation#1512) until a fix could be put in place (this).

@daveinglis
Copy link
Author

@swift-ci test

@daveinglis
Copy link
Author

@parkera Is my last comment clear on where this prefix is originating from? I would like to resurrect this (swiftlang/swift-foundation#1479) foundation change that was reverted once this goes in.

}

// Strip UNC long path prefixe (\\?\) from the wide character buffer using PathCchStripPrefix
wchar_t *pathToConvert = buf;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of adding to this _NS_getcwd, I wonder if we should just make this call to the implementation in swift-foundation. Is it feasible to call from CF to a Foundation @_cdecl function here? That way it could call to swift-foundation via FileManager and then we'd be using the same "get CWD" implementation everywhere instead of maintaining two copies of it.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Foundation call that I think you are referring to would be in Sources/FoundationEssentials/FileManager/FileManager+Directories.swift, specifically

var currentDirectoryPath: String? { .... }

Is that right? But since we can't @_cdecl a computed property, this would require some refactoring. Is this the route we want to take?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it's possible to make the call from CF to Swift here, I think it would just require a small @_cdecl hop to FileManager.default.currentDirectoryPath. We've used this approach in other places such as here:

https://github.com/swiftlang/swift-foundation/blob/7566cd462073afbdf16ac846d9018d4d0c42c147/Sources/FoundationEssentials/FileManager/SearchPaths/FileManager%2BDarwinSearchPaths.swift#L158-L161

In that case, we added a small C-visible entry point that maps to an appropriate Swift API so that CF can call the Swift API instead of re-implementing the logic in C. if it's feasible to do that here, that sounds like a good direction

Copy link
Author

@daveinglis daveinglis Oct 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this swiftlang/swift-foundation#1545 what you had in mind? I can update this PR to use it once it's in if so. Or do you want this method in this PR local to this package?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah something like that looks good to me if we can call it from CF (I know CF on Darwin upward links Foundation to perform calls like this, not sure if we do that on Linux/Windows too). But I think we can define that cdecl function here in SCL-F since it uses only public API (right) - that way we can just define it and use it here in the same PR


// Get original directory for restoration
var originalBuffer = [CChar](repeating: 0, count: Int(MAX_PATH))
guard _NS_getcwd(&originalBuffer, originalBuffer.count) != nil else {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of calling directly to _NS_getcwd from the test, it'd be great if this test could call the client-level API that this affects. So if changing _NS_getcwd is required here because it impacts the FSR of an NSURL, could we instead write a test that checks the output of NSURL's FSR to ensure it's the right value? To me that would be a more valuable unit test to make sure the client level behavior is correct regardless of the output of this function (since as we remove more and more C code this function may go away, but our Swift API won't)

- FileManager handles long file name prefixes on Windows correctly.
  This keeps any UNC long file prefix (\\?\) out of
  URL that were relative and then resolved to absolute urls.
@daveinglis daveinglis changed the title Strip any UNC long path prefix from _wgetcwd Use FileManager API to get current working directory Oct 15, 2025
@daveinglis
Copy link
Author

@swift-ci test

@daveinglis
Copy link
Author

@swift-ci test

@daveinglis
Copy link
Author

@swift-ci test windows

@daveinglis
Copy link
Author

@swift-ci test windows

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants